<template>
  <div class="draw-board">
    <div id="container" ref="container"></div>
  </div>
</template>

<script>
import { initGraph, createBasicPointNode } from "@/utils/graphUtils.js";
import { Addon, Shape } from "@antv/x6";
import { mapMutations, mapState } from "vuex";
import { getuuid } from "@/utils";
let topolog;
export default {
  data() {
    return {
      dnd: null, // 用于绘制元素
      sourceNode: null, // 开始节点
      targetNode: null, // 结束节点
    };
  },
  computed: {
    ...mapState([
      "currentObj",
      "currentOperation",
      "currentLine",
      "currentSetting",
      "currentPen",
      "currentTextPen",
    ]),
    showFlag() {
      if (this.currentOperation && this.currentOperation.type == "links") {
        if (this.currentLine.dbm) {
          if (this.currentOperation.title) return true;
          return true;
        }
        return false;
      } else {
        if (
          this.currentOperation &&
          this.currentOperation.title &&
          this.currentOperation.type === "point"
        )
          return true;
        return false;
      }
    },
  },
  watch: {
    showFlag: function (val, oldval) {
      if (this.showFlag) {
        window.$graph.on("blank:mousedown", this.mousedownHandler);
      } else {
        this.sourceNode = null;
        this.targetNode = null;
        window.$graph.off("blank:mousedown", this.mousedownHandler);
      }
    },
  },
  mounted() {
    initGraph(this.$refs.container);
    this.initGraphEvent();
    // 拖拽处理
    this.dnd = new Addon.Dnd({
      target: window.$graph,
      getDragNode: (node) => {
        return createBasicPointNode(this.currentObj);
      },
      getDropNode: (node) => {
        return node.clone();
      },
    });
  },
  methods: {
    ...mapMutations(["setData"]),
    edgeClickHandler({ edge }) {
      this.currentPen &&
        this.currentPen.attr({ body: { opacity: 1 }, line: { opacity: 1 } });
      if (this.currentTextPen) {
        this.setData({
          currentTextPen: null,
        });
      }
      this.setData({
        currentPen: edge,
      });
      if (this.showFlag) {
      } else {
        edge.attr({ line: { opacity: 0.5 } });
      }
    },
    nodeClickHandler({ node }) {
      this.currentPen &&
        this.currentPen.attr({ body: { opacity: 1 }, line: { opacity: 1 } });
      this.currentTextPen &&
        this.currentTextPen.attr({ label: { opacity: 1 } });
      let { node: dealNode, textNode: dealTextNode } = this.updateStoreNode(
        node.id
      );

      if (
        this.showFlag ||
        (this.currentOperation && this.currentOperation.type == "link")
      ) {
        // 更新车站里面的线路信息

        // 增加连线
        this.addLine(dealNode);
        if (this.currentOperation && this.currentOperation.type == "link") {
          dealNode.attr({ body: { opacity: 0.5 } });
          dealTextNode.attr({ label: { opacity: 0.5 } });
        }
      } else {
        // 选中状态，修改透明度
        dealNode.attr({ body: { opacity: 0.5 } });
        dealTextNode.attr({ label: { opacity: 0.5 } });
      }
    },
    mousedownHandler({ e, x, y }) {
      let point = this.currentObj.point;
      let circle = {
        shape: point.shape,
        width: point.width,
        height: point.height,
        zIndex: point.zIndex,
        attrs: {
          body: {
            fill: point.fill,
            stroke: point.stroke,
            strokeWidth: point.strokeWidth,
          },
        },
      };
      this.dnd && this.dnd.start(circle, e);
    },
    nodeAddedHandler({ node }) {
      // 如果不是车站节点，直接返回
      if (node.data.type === "text") return;
      let { point, text, link } = this.currentObj;
      // 1. 增加相关的属性，比如关联的线， 线路信息
      node.setData({
        tags: ["station"],
        sn: text.text,
        sdbm: text.dbm,
        // ln: [this.currentObj.name], // 线路可以是多个
        // ldbm: [this.currentObj.dbm],
        ln:
          this.currentObj && this.currentObj.name ? [this.currentObj.name] : [],
        ldbm:
          this.currentObj && this.currentObj.dbm ? [this.currentObj.dbm] : [],
        links: [],
      });
      let { x, y } = node.getPosition();
      // 2. 增加文本节点
      let textdx = 0 + point.width / 2;
      let textdy = 0 - text.fontSize;
      let textId = node.id + "-text";
      let textNode = new Shape.Rect({
        id: textId,
        x: x + textdx,
        y: y + textdy,
        zIndex: text.zIndex,
        attrs: {
          body: {
            fill: "transparent",
            stroke: "transparent",
            width: 0,
          },
          label: {
            text: text.text,
            fill: text.fill,
            fontSize: text.fontSize,
          },
        },
        data: {
          type: "text",
          tags: ["text"],
        },
      });
      window.$graph.addNode(textNode);
      // 2.1 将信息更新到属性栏中
      let size = node.size();
      let { circle } = node.getAttrs();
      this.setData({
        currentSetting: {
          x: x,
          y: y,
          h: size.height,
          w: size.width,
          lineWidth: circle.strokeWidth,
          lineColor: circle.stroke,
          bkcolor: circle.fill,
          fontsize: text.fontSize,
          fontcolor: text.fill,
          textdx: textdx,
          textdy: textdy,
          text: text.text,
          kId: text.dbm, // 车站dbm
          id: node.id,
          dynamicTags: [],
          ln:
            this.currentObj && this.currentObj.name
              ? [this.currentObj.name]
              : [],
          ldbm:
            this.currentObj && this.currentObj.dbm ? [this.currentObj.dbm] : [],
        },
        currentPen: node,
        currentTextPen: window.$graph.getCellById(textId),
      });

      if (!link) return;
      // 3. 增加连线
      this.addLine(node);
    },
    updateStoreNode(nodeId) {
      let node = null;
      let textNode = null;
      if (nodeId.includes("text")) {
        // 文本节点
        textNode = window.$graph.getCellById(nodeId);
        node = window.$graph.getCellById(
          nodeId.substring(0, nodeId.length - 5)
        );
      } else {
        // 正常节点
        node = window.$graph.getCellById(nodeId);
        textNode = window.$graph.getCellById(nodeId + "-text");
      }
      let id = node.id;
      let data = node.getData();

      if (this.currentObj && this.currentObj.name) {
        // 设置连线信息
        if (data.ln.includes(this.currentObj.name)) {
        } else {
          if (this.showFlag) {
            node.setData({
              ln: [...data.ln, this.currentObj.name],
              ldbm: [...data.ldbm, this.currentObj.dbm],
            });
          }
        }
      }

      let { x, y } = node.getPosition();
      let size = node.size();
      let { circle } = node.getAttrs();
      // 文本节点
      let { x: textX, y: textY } = textNode.getPosition();
      let { label } = textNode.getAttrs();
      let newData = node.getData();
      let dataTemp = {
        x: x,
        y: y,
        h: size.height,
        w: size.width,
        lineWidth: circle.strokeWidth,
        lineColor: circle.stroke,
        bkcolor: circle.fill,
        fontsize: label.fontSize,
        fontcolor: label.fill,
        textdx: textX - x,
        textdy: textY - y,
        text: label.text,
        kId: data.sdbm,
        id: id,
        dynamicTags: data.tags,
        ln: newData.ln,
        ldbm: newData.ldbm,
      };
      this.setData({
        currentSetting: dataTemp,
        currentPen: node,
        currentTextPen: textNode,
      });
      return {
        node,
        textNode,
      };
    },
    // 增加连线
    addLine(node) {
      let { link } = this.currentObj;
      if (!this.targetNode) {
        // 普通连线时状态栏的提示信息
        this.setData({
          currentObj: { ...this.currentObj, NodeIndex: 2 },
        });
        this.targetNode = node;
      } else {
        this.sourceNode = this.targetNode;
        this.targetNode = node;
        // 判断当前的新增的连线是否在节点里面
        let realSourceLinks = this.sourceNode.getData().links;
        let realTargetLinks = this.targetNode.getData().links;
        let flag = "";
        let realTargetLinksObj = {};
        realTargetLinks.forEach((link) => {
          realTargetLinksObj[link] = true;
        });
        for (let i = 0; i < realSourceLinks.length; i++) {
          const rlink = realSourceLinks[i];

          if (realTargetLinksObj[rlink]) {
            flag = rlink;
            break;
          }
        }

        // 如果存在，直接更新线路信息到 线 上
        // 如果不存在， 就绘制一条新线
        if (flag) {
          // 更新既有的连线
          let edgeHaven = window.$graph.getCellById(flag);
          let edgeHavenData = edgeHaven.getData();
          let { tags, ln, ldbm } = edgeHavenData;
          let tempData = {};
          if (
            this.currentObj &&
            this.currentObj.dbm &&
            !tags.includes(this.currentObj.dbm)
          ) {
            tempData.tags = [...tags, this.currentObj.dbm];
          }
          if (
            this.currentObj &&
            this.currentObj.name &&
            !ln.includes(this.currentObj.name)
          ) {
            tempData.ln = [...ln, this.currentObj.name];
          }
          if (
            this.currentObj &&
            this.currentObj.dbm &&
            !ldbm.includes(this.currentObj.dbm)
          ) {
            tempData.ldbm = [...ldbm, this.currentObj.dbm];
          }

          edgeHaven.setData(tempData, {
            deep: false,
          });
        } else {
          let lineId = getuuid(4);
          window.$graph.addEdge({
            id: lineId,
            shape: link.shape,
            source: {
              cell: this.sourceNode,
            },
            target: {
              cell: this.targetNode,
            },
            attrs: {
              line: {
                sourceMarker: null,
                targetMarker: null,
                stroke: this.currentObj.color,
              },
            },
            data: {
              tags:
                this.currentObj && this.currentObj.dbm
                  ? ["line", this.currentObj.dbm]
                  : ["line"],
              ln:
                this.currentObj && this.currentObj.name
                  ? [this.currentObj.name]
                  : [],
              ldbm:
                this.currentObj && this.currentObj.dbm
                  ? [this.currentObj.dbm]
                  : [],
              from: this.sourceNode.id,
              to: this.targetNode.id,
            },
          });
          let { links } = this.sourceNode.getData();
          if (links.includes(lineId)) {
          } else {
            this.sourceNode.setData({
              links: [...links, lineId],
            });
          }
          let { links: linksTarget } = this.targetNode.getData();
          if (linksTarget.includes(lineId)) {
          } else {
            this.targetNode.setData({
              links: [...linksTarget, lineId],
            });
          }
        }
      }
    },
    // 画布事件初始化
    initGraphEvent() {
      // 点击节点
      window.$graph.on("node:click", this.nodeClickHandler);
      // 点击空白处
      window.$graph.on("blank:click", () => {
        this.currentPen &&
          this.currentPen.attr({ body: { opacity: 1 }, line: { opacity: 1 } });
        this.currentTextPen &&
          this.currentTextPen.attr({ label: { opacity: 1 } });
        this.sourceNode = null;
        this.targetNode = null;
        this.setData({
          currentObj: { ...this.currentObj, NodeIndex: 1 },
        });
        this.setData({
          currentPen: null,
          currentTextPen: null,
        });
      });
      // 点击线
      window.$graph.on("edge:click", this.edgeClickHandler);
      // 新建节点
      window.$graph.on("node:added", this.nodeAddedHandler);
      // // 新建线
      // window.$graph.on("edge:added", this.lineAddedHandler);

      // window.$graph.on("node:dblclick", this.nodeDoubleClickHandler);
      // window.$graph.on("edge:removed", this.edgeRemovedHandler);
      // window.$graph.on("node:removed", this.nodeRemovedHandler);
    },
  },
};
</script>
<style lang="scss" scoped>
.draw-board {
  width: 100%;
  height: 100%;
  background: #eee;
  #container {
    width: 100%;
    height: 100%;
    // width: 900px;
    // height:500px;
    // overflow: hidden;
    // width: 500px;
    // height: 500px;
  }
}
</style>
